package com.minio.learning.springminio.resp;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.minio.learning.springminio.util.TimeUtils;
import com.minio.learning.springminio.util.UuidUtils;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

/**
 * @author YanXxx
 */
@Data
@Slf4j
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CommonResult<T> {

    private static final String ERR_MSG = "操作失败!";

    private static final String SUC_MSG = "操作成功!";
    /**
     * 响应状态
     */
    private Integer status;

    /**
     * 响应消息
     */
    private String msg;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 数据总条数
     */
    private Long total;

    /**
     * 请求id
     */
    private String requestId;

    /**
     * 时间戳
     */
    private Long timestamp;

    /**
     * 统一响应构造器
     */
    public CommonResult() {
        super();
    }

    /**
     * 统一响应构造器
     *
     * @param status 状态码
     * @param msg    消息内容
     * @param data   数据对象
     */
    public CommonResult(Integer status, String msg, T data, String requestId, Long timestamp) {
        this.status = status;
        this.msg = msg;
        this.data = data;
        this.timestamp = timestamp;
        this.requestId = requestId;
        log.info("请求Id:{},时间戳:{},状态码:{},消息内容:{},数据对象:{}",
                requestId, timestamp, status, msg, data);
    }

    /**
     * 统一响应构造器
     *
     * @param status    状态码
     * @param msg       消息内容
     * @param data      数据对象
     * @param count     总数
     * @param requestId 请求ID
     * @param timestamp 时间戳
     */
    public CommonResult(Integer status, String msg, T data, Long count, String requestId, Long timestamp) {
        this.status = status;
        this.msg = msg;
        this.data = data;
        this.total = count;
        this.timestamp = timestamp;
        this.requestId = requestId;
        log.info("请求Id:{},时间戳:{},状态码:{},消息内容:{},数据对象:{},总数:{}",
                requestId, timestamp, status, msg, data, total);
    }

    /**
     * 统一响应构建方法
     *
     * @return 无
     */
    public static <T> CommonResult<T> build() {
        return new CommonResult<>();
    }

    /**
     * 统一响应构建方法
     *
     * @param status 状态码
     * @param msg    消息内容
     * @param data   数据对象
     * @return 返回结果
     */
    public static <T> CommonResult<T> build(Integer status, String msg, T data) {
        return new CommonResult<>(status, msg, data, UuidUtils.getUUID(), TimeUtils.getTimestamp());
    }

    /**
     * 统一响应构建方法
     *
     * @param status 状态码
     * @param data   数据对象
     * @return 返回结果
     */
    public static <T> CommonResult<T> build(Integer status, T data) {
        return new CommonResult<>(status, ERR_MSG,
                data, UuidUtils.getUUID(), TimeUtils.getTimestamp());
    }

    /**
     * 统一响应构建方法
     *
     * @param status 状态码
     * @return 返回结果
     */
    public static CommonResult<?> build(Integer status) {
        return new CommonResult<>(status, ERR_MSG, null,
                UuidUtils.getUUID(), TimeUtils.getTimestamp());
    }

    /**
     * 统一响应构建方法
     *
     * @param status 状态码
     * @param msg    消息内容
     * @param data   数据对象
     * @param total  总条数
     * @return 返回结果
     */
    public static <T> CommonResult<T> build(Integer status, String msg, T data, Long total) {
        return new CommonResult<>(status, msg, data, total, UuidUtils.getUUID(), TimeUtils.getTimestamp());
    }

    /**
     * 统一响应-返回成功
     *
     * @return 返回结果
     */
    public static <T> CommonResult<T> ok() {
        return build(200, SUC_MSG, null);
    }

    /**
     * 统一响应-返回成功
     *
     * @param msg 消息内容
     * @return 返回结果
     */
    public static <T> CommonResult<T> ok(String msg) {
        return build(200, msg, null);
    }

    /**
     * 统一响应-返回成功
     *
     * @param msg  消息内容
     * @param data 数据对象
     * @return 返回结果
     */
    public static <T> CommonResult<T> ok(String msg, T data) {
        return build(200, msg, data);
    }

    /**
     * 统一响应-返回成功
     *
     * @param msg   消息内容
     * @param data  数据对象
     * @param total 总条数
     * @return 返回结果
     */
    public static <T> CommonResult<T> ok(String msg, T data, Long total) {
        return build(200, msg, data, total);
    }

    /**
     * 统一响应-返回失败
     *
     * @return 返回结果
     */
    public static <T> CommonResult<T> error() {
        return build(100, ERR_MSG, null);
    }

    /**
     * 统一响应-返回失败
     *
     * @param msg 消息内容
     * @return 返回结果
     */
    public static <T> CommonResult<T> error(String msg) {
        return build(100, msg, null);
    }

    /**
     * 统一响应-返回失败
     *
     * @param msg  消息内容
     * @param data 数据对象
     * @return 返回结果
     */
    public static <T> CommonResult<T> error(String msg, T data) {
        return build(100, msg, data);
    }
}
